package com.java1234.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.java1234.entity.SysMenu;
import com.java1234.entity.SysRole;
import com.java1234.entity.SysUser;
import com.java1234.entity.SysUserRole;
import com.java1234.mapper.SysMenuMapper;
import com.java1234.mapper.SysRoleMapper;
import com.java1234.mapper.SysUserMapper;
import com.java1234.mapper.SysUserRoleMapper;
import com.java1234.service.SysUserService;
import com.java1234.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    /**
     * 注册用户，只检查用户名是否已存在，并且为用户分配默认角色ID 35。
     *
     * @param user 用户信息
     */
    @Override
    @Transactional
    public void registerUser(SysUser user) {
        // 加密密码
        user.setPassword(passwordEncoder.encode(user.getPassword()));

        // 检查用户名是否已存在
        if (this.getByUsername(user.getUsername()) != null) {
            throw new RuntimeException("用户名已存在");
        }

        // 设置默认状态和其他必要的字段
        user.setStatus("0"); // 假设 '0' 是正常状态
        user.setLoginDate(null);

        // 保存用户信息到数据库
        save(user);

        // 创建新的用户-角色关系，使用默认的角色ID 35
        SysUserRole userRole = new SysUserRole();
        userRole.setUserId(user.getId());
        userRole.setRoleId(35L);
        sysUserRoleMapper.insert(userRole);
    }

    /**
     * 根据用户名获取用户信息
     */
    @Override
    public SysUser getByUsername(String username) {
        return getOne(new QueryWrapper<SysUser>().eq("username", username));
    }

    /**
     * 获取用户的权限信息（角色和菜单权限）
     */
    @Override
    public String getUserAuthorityInfo(Long userId) {
        StringBuilder authority = new StringBuilder();

        // 根据用户id获取所有的角色信息
        List<SysRole> roleList = sysRoleMapper.selectList(
                new QueryWrapper<SysRole>()
                        .inSql("id", "SELECT role_id FROM sys_user_role WHERE user_id=" + userId)
        );

        if (!roleList.isEmpty()) {
            String roleCodeStrs = roleList.stream()
                    .map(r -> "ROLE_" + r.getCode())
                    .collect(Collectors.joining(","));
            authority.append(roleCodeStrs);
        }

        // 遍历所有角色，获取所有菜单权限并且不重复
        Set<String> menuCodeSet = new HashSet<>();
        roleList.forEach(sysRole -> {
            List<SysMenu> sysMenuList = sysMenuMapper.selectList(
                    new QueryWrapper<SysMenu>()
                            .inSql("id", "SELECT menu_id FROM sys_role_menu WHERE role_id=" + sysRole.getId())
            );
            sysMenuList.stream()
                    .filter(sysMenu -> StringUtil.isNotEmpty(sysMenu.getPerms()))
                    .forEach(sysMenu -> menuCodeSet.add(sysMenu.getPerms()));
        });

        if (!menuCodeSet.isEmpty()) {
            if (authority.length() > 0) {
                authority.append(",");
            }
            authority.append(String.join(",", menuCodeSet));
        }

        return authority.toString();
    }

    /**
     * 检查用户名是否存在。
     */
    @Override
    public boolean checkUsernameExists(String username) {
        return count(new QueryWrapper<SysUser>().eq("username", username)) > 0;
    }

    /**
     * 检查手机号是否存在。
     */
    @Override
    public boolean checkPhonenumberExists(String phonenumber) {
        return count(new QueryWrapper<SysUser>().eq("phonenumber", phonenumber)) > 0;
    }

    /**
     * 重置用户密码。
     */
    @Override
    @Transactional
    public boolean resetPassword(String username, String phonenumber, String hashedNewPassword) {
        SysUser user = getByUsername(username);
        if (user != null && user.getPhonenumber().equals(phonenumber)) {
            // 直接设置已经加密的新密码并打印日志
            user.setPassword(hashedNewPassword);

            return updateById(user);
        } else {
            return false;
        }
    }
}